package org.alwayssuper.protocol.commons.transform.realtimev2025;

import org.alwayssuper.protostar.annotation.Field;
import lombok.Data;
import lombok.ToString;
import lombok.experimental.Accessors;

/**
 * 2025版车辆位置数据格式 (0x05)
 * 参考GB/T 32960.3-2025标准表21-22
 * @author alwaysSuper
 */
@ToString
@Data
@Accessors(chain = true)
public class VehicleLocationData {
    @Field(length = 1, desc = "定位状态:状态位定义见表22")
    private int positionStatus;
    
    @Field(length = 1, desc = "坐标系:0x01:WGS84坐标系;0x02:GCJ02坐标系;0x03:其他坐标系")
    private int coordinateSystem;
    
    @Field(length = 4, desc = "经度:以度为单位的经度值乘以10^6,精确到百万分之一度")
    private int longitude;
    
    @Field(length = 4, desc = "纬度:以度为单位的纬度值乘以10^6,精确到百万分之一度")
    private int latitude;
    
    // 定位状态位定义常量 - 基于GB/T32960.3-2025标准表22
    public static final int POSITIONING_VALID_BIT = 0;          // 位0: 0:有效定位 1:无效定位
    public static final int LATITUDE_DIRECTION_BIT = 1;         // 位1: 0:北纬 1:南纬
    public static final int LONGITUDE_DIRECTION_BIT = 2;        // 位2: 0:东经 1:西经
    // 位3~7: 预留
    
    /**
     * 检查定位是否有效
     * @return true: 有效定位, false: 无效定位
     */
    public boolean isPositioningValid() {
        return (positionStatus & (1 << POSITIONING_VALID_BIT)) == 0;
    }
    
    /**
     * 检查纬度方向
     * @return true: 南纬, false: 北纬
     */
    public boolean isSouthLatitude() {
        return (positionStatus & (1 << LATITUDE_DIRECTION_BIT)) != 0;
    }
    
    /**
     * 检查经度方向
     * @return true: 西经, false: 东经
     */
    public boolean isWestLongitude() {
        return (positionStatus & (1 << LONGITUDE_DIRECTION_BIT)) != 0;
    }
    
    /**
     * 获取经度值（带方向）
     * @return 经度值（度）
     */
    public double getLongitude() {
        double lonValue = longitude / 1000000.0;
        return isWestLongitude() ? -lonValue : lonValue;
    }
    
    /**
     * 获取纬度值（带方向）
     * @return 纬度值（度）
     */
    public double getLatitude() {
        double latValue = latitude / 1000000.0;
        return isSouthLatitude() ? -latValue : latValue;
    }
    
    /**
     * 获取经度方向描述
     * @return 经度方向字符串
     */
    public String getLongitudeDirection() {
        return isWestLongitude() ? "西经" : "东经";
    }
    
    /**
     * 获取纬度方向描述
     * @return 纬度方向字符串
     */
    public String getLatitudeDirection() {
        return isSouthLatitude() ? "南纬" : "北纬";
    }
    
    /**
     * 获取坐标系描述
     * @return 坐标系描述字符串
     */
    public String getCoordinateSystemDescription() {
        switch (coordinateSystem) {
            case 0x01:
                return "WGS84坐标系";
            case 0x02:
                return "GCJ02坐标系";
            case 0x03:
                return "其他坐标系";
            default:
                return "未知坐标系(" + String.format("0x%02X", coordinateSystem) + ")";
        }
    }
    
    /**
     * 获取定位状态的二进制字符串表示
     * @return 8位二进制字符串
     */
    public String getPositionStatusBinaryString() {
        return String.format("%8s", Integer.toBinaryString(positionStatus)).replace(' ', '0');
    }
    
    /**
     * 获取定位状态的十六进制字符串表示
     * @return 十六进制字符串
     */
    public String getPositionStatusHexString() {
        return String.format("0x%02X", positionStatus);
    }
    
    /**
     * 获取完整的位置信息描述
     * @return 位置信息描述字符串
     */
    public String getLocationDescription() {
        if (!isPositioningValid()) {
            return "无效定位";
        }
        
        StringBuilder sb = new StringBuilder();
        sb.append(getCoordinateSystemDescription()).append(": ");
        sb.append(String.format("%.6f", Math.abs(getLongitude())));
        sb.append("°").append(getLongitudeDirection()).append(", ");
        sb.append(String.format("%.6f", Math.abs(getLatitude())));
        sb.append("°").append(getLatitudeDirection());
        
        return sb.toString();
    }
    
    /**
     * 验证经纬度的合法性
     * @return true: 合法, false: 不合法
     */
    public boolean isValidCoordinates() {
        if (!isPositioningValid()) {
            return false;
        }
        
        double realLon = Math.abs(getLongitude());
        double realLat = Math.abs(getLatitude());
        
        // 经度范围: -180° ~ +180°
        // 纬度范围: -90° ~ +90°
        return realLon <= 180.0 && realLat <= 90.0;
    }
    
    /**
     * 转换为WGS84坐标系的经纬度数组
     * @return [longitude, latitude] 数组，如果定位无效则返回null
     */
    public double[] toWGS84Coordinates() {
        if (!isPositioningValid() || !isValidCoordinates()) {
            return null;
        }
        
        double lon = getLongitude();
        double lat = getLatitude();
        
        // 如果是GCJ02坐标系，需要转换为WGS84（这里仅为示例，实际应用需要精确的坐标转换算法）
        if (coordinateSystem == 0x02) {
            // GCJ02 to WGS84 转换（简化版，实际应用需要更精确的算法）
            // 这里只是示例，实际项目中应使用专业的坐标转换库
            System.out.println("警告: GCJ02坐标转换为WGS84需要专业算法，当前返回原始数据");
        }
        
        return new double[]{lon, lat};
    }
}